#pragma once

#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/base/Logging.h>

std::string readFile(const char* filename)
{
  std::string content;
  FILE* fp = ::fopen(filename, "rb");
  if (fp)
  {
    // inefficient!!!
    const int kBufSize = 1024*1024;
    char iobuf[kBufSize];// 标准库指定的缓冲区变到这里来了
    setbuffer(fp, iobuf, sizeof iobuf);// 自定义文件流的缓冲区

    char buf[kBufSize];
    size_t nread = 0;
    while ( (nread = fread(buf, 1, sizeof buf, fp)) > 0)// 一个一个字节读？？？
    {
      content.append(buf, nread);
    }
    fclose(fp);
  }
  return std::move(content);// 避免一次拷贝，直接构造
}

char *file_name = nullptr;
class FileServer
{
public:
    FileServer(muduo::net::EventLoop *loop,const muduo::net::InetAddress &listenAddr)
        :_server(loop,listenAddr,"FileServer")
    {
        _server.setConnectionCallback(std::bind(&FileServer::connection_handler,this,std::placeholders::_1));
        _server.setMessageCallback(std::bind(&FileServer::message_handler,this,
        std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
    }

    void start()
    {
        _server.start();
    }
    
    void connection_handler(const muduo::net::TcpConnectionPtr &conn)
    {
        LOG_INFO << "FileServer - " << conn->peerAddress().toIpPort() << " -> "
        << conn->localAddress().toIpPort() << " is "
        << (conn->connected() ? "UP" : "DOWN");

        if(conn->connected())
        {
            LOG_INFO << "FileServer -> Sending File " << file_name << " to "
            << conn->peerAddress().toIpPort();
            std::string file_content = readFile(file_name);
            conn->send(file_content);
            conn->shutdown();
            LOG_INFO << "FileServer - done";
        }
    }

    void message_handler(const muduo::net::TcpConnectionPtr &conn,muduo::net::Buffer *buf,muduo::Timestamp time)
    {
        std::string msg(buf->retrieveAllAsString());
        LOG_INFO << conn->name() << " discards " << msg.size()
            << " bytes received at " << time.toString();
    }
protected:
    muduo::net::TcpServer _server;
};